import React, { ReactNode, useState, useEffect, createRef, FC } from 'react'
import { PlayerListPanel } from './style'
import PlayerScroll from '../app-player-scroll'
import { Singer, Song } from '@/types/common-types'
import { formatTime, formatSingerName } from '@/utils/format'
import { useAppSelector, useAppDispatch, shallowEqualApp } from '@/store'
import {
  removeOneMusicAction,
  clearPlaySongListAction,
  changeCurrentSongAction,
  changePlaySongIndexAction,
  seekLyric
} from '@/views/player/store/player'

interface IProps {
  children?: ReactNode
  panelVisible: boolean
  songList: Song[]
  hidePlayerPanel: () => void
  resetPlaySlider: () => void
  removeOneMuiscEffect: () => void
}

const PlayerPanel: FC<IProps> = (props) => {
  const [scrollY, setScrollY] = useState(0)
  const [scrollY2, setScrollY2] = useState(0)
  const songListRef = createRef<PlayerScroll>()
  const lyricListRef = createRef<PlayerScroll>()
  const dispatch = useAppDispatch()
  const { currentSong, lyrics, lyricIndex, playSongIndex } = useAppSelector(
    (state) => ({
      currentSong: state.player.currentSong,
      lyrics: state.player.lyrics,
      lyricIndex: state.player.lyricIndex,
      playSongIndex: state.player.playSongIndex
    }),
    shallowEqualApp
  )
  const {
    songList,
    panelVisible,
    hidePlayerPanel,
    resetPlaySlider,
    removeOneMuiscEffect
  } = props
  // 清空全部歌曲
  function removePlaySongList(): void {
    dispatch(clearPlaySongListAction())
    resetPlaySlider()
  }
  // 清空一首歌曲
  function removOneMuisc(e: MouseEvent, id: number): void {
    e.stopPropagation()
    if (songList.length === 1) {
      removePlaySongList()
    } else {
      dispatch(removeOneMusicAction(id))
      removeOneMuiscEffect()
    }
  }
  // 播放选中的歌曲
  function changeCurrentSong(song: Song, index: number): void {
    dispatch(changePlaySongIndexAction(index))
    dispatch(changeCurrentSongAction(song))
    seekLyric(song.id, dispatch)
  }
  // 歌曲列表滚动值scrollY
  function onScrollSongListEnd(y: number) {
    setScrollY(y)
  }
  // 歌词列表滚动值scrollY
  function onScrollLyricEnd(y: number) {
    setScrollY2(y)
  }
  // 歌曲/歌词滚动到指定位置
  function scrollToCurrentEle(
    tag: string,
    index: number,
    scrollY: number,
    type: 'song' | 'lyric',
    speed = 300
  ) {
    if (!songListRef.current) return
    if (!lyricListRef.current) return
    let offsetNum = 5
    const dom = document.getElementById(tag) as HTMLDivElement
    const listRefs = dom.children[0].querySelectorAll('ul > li')
    if (listRefs.length) {
      const currentLi = listRefs[index || 0] as HTMLLIElement
      if (!currentLi) return
      const offsetTop = currentLi.offsetTop
      const offsetHeight = currentLi.offsetHeight
      // 双语歌词
      if (type === 'lyric' && offsetHeight > 40) {
        offsetNum = 3
      }
      // 非双语歌词
      if (type === 'lyric' && offsetHeight < 40) {
        offsetNum = 7
      }
      const firstCon = offsetTop - Math.abs(scrollY) > offsetHeight * offsetNum
      const secondCon = offsetTop < Math.abs(scrollY)
      if (firstCon || secondCon) {
        if (type === 'song') {
          songListRef.current.scrollToElement(currentLi, speed, false, false)
        } else {
          lyricListRef.current.scrollToElement(currentLi, speed, false, false)
        }
      }
    }
  }
  useEffect(() => {
    if (panelVisible) {
      scrollToCurrentEle('song-list', playSongIndex, scrollY, 'song', 0)
      scrollToCurrentEle('lyric-list', lyricIndex, scrollY2, 'lyric', 0)
    }
  }, [panelVisible, playSongIndex, lyricIndex])
  return (
    <PlayerListPanel
      className={`${panelVisible ? 'player-panel' : 'playerPanel-hide'}`}
    >
      <div className="hd">
        <div className="hdc">
          <h4>
            播放列表(<span>{songList.length}</span>)
          </h4>
          <div className="add-all">
            <i className="icon" title="收藏全部"></i>收藏全部
          </div>
          <span className="line"></span>
          <div className="clear-all" onClick={removePlaySongList}>
            <i className="icon trush" title="清除"></i> 清除
          </div>
          <div className="playing-name">{currentSong?.name}</div>
          <i className="icon close" onClick={() => hidePlayerPanel()}></i>
        </div>
      </div>
      <div className="bd">
        <div className="mask">
          <div id="song-list" className="list-wrap">
            <PlayerScroll
              ref={songListRef}
              panelShow={panelVisible}
              data={songList}
              onScrollEnd={onScrollSongListEnd}
            >
              <ul>
                {songList.map((song, index) => {
                  return (
                    <li
                      className={playSongIndex === index ? 'current' : ''}
                      key={song.id}
                      onClick={() => changeCurrentSong(song, index)}
                    >
                      <i className="col arrow"></i>
                      <div className="col name ellipsis">{song.name}</div>
                      <div className="col icons">
                        <i className="ico like" title="收藏"></i>
                        <i className="ico share" title="分享"></i>
                        <i
                          className="ico trush"
                          title="删除"
                          onClick={(e: any) => removOneMuisc(e, song.id)}
                        ></i>
                      </div>
                      <div className="singers clearfix ellipsis">
                        {song?.ar.map((singer: Singer) => {
                          return (
                            <div className="singer-item" key={singer.id}>
                              <a className="col ellipsis">
                                {formatSingerName(song.ar)}
                              </a>
                            </div>
                          )
                        })}
                      </div>
                      <div className="col duration">
                        {formatTime(song.dt / 1000)}
                      </div>
                      <div className="col link"></div>
                    </li>
                  )
                })}
              </ul>
            </PlayerScroll>
          </div>
        </div>
        <div id="lyric-list" className="list-lyric">
          <PlayerScroll
            ref={lyricListRef}
            data={lyrics}
            panelShow={panelVisible}
            onScrollEnd={onScrollLyricEnd}
          >
            <ul>
              {lyrics.map((lyric, index) => {
                return (
                  <li
                    key={index}
                    className={lyricIndex === index ? 'current' : ''}
                    dangerouslySetInnerHTML={{ __html: lyric.text }}
                  ></li>
                )
              })}
            </ul>
          </PlayerScroll>
        </div>
      </div>
    </PlayerListPanel>
  )
}

export default PlayerPanel
